package com.bawan.utils;

import com.bawan.common.Constants;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Desc: 日期常用工具类
 * User: ZhengCongChun
 * Date: 14-2-20
 * Time: 上午10:06
 *
 * @Version 1.0
 */
public class DateCommonUtil {
    private static Logger logger = Logger.getLogger(DateCommonUtil.class);

    /**
     * 匹配传入的日期时间参数与相关的格式是否匹配
     *
     * @param datetime
     * @param format   (yyyy-MM-dd HH:mm:ss / HH:mm:ss / yyyy-MM-dd)
     * @return
     */
    public static boolean matcherDateFormat(String datetime, String format) {
        if (StringUtils.isBlank(datetime) || StringUtils.isBlank(format)) {
            logger.error("==== 两日期时间参数不能为空 ====");
            return false;
        }
        //yyyy-MM-dd HH:mm:ss
        String el = "";
        if (format.equalsIgnoreCase(Constants.DATE_TIME_FULL_FORMAT)) {
            el = "^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}$";
        }
        if (format.equalsIgnoreCase(Constants.TIME_FORMAT)) {
            el = "^\\d{2}:\\d{2}:\\d{2}$";
        }
        if (format.equalsIgnoreCase(Constants.DATE_FORMAT)) {
            el = "^\\d{4}-\\d{2}-\\d{2}$";
        }
        if (format.equalsIgnoreCase(Constants.DATE_TIME_FULL_FORMAT_STR)) {
            el = "^[1,2]\\d{3}[0,1]\\d{3}$";
        }
        if (format.equalsIgnoreCase(Constants.DATE_TIME_FULL_FORMAT_MINUTE)) {
            el = "^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}$";
        }
        Pattern pattern = Pattern.compile(el);
        Matcher matcher = pattern.matcher(datetime);
        return matcher.matches();
    }

    /**
     * 计算一个日期是星期几
     *
     * @param dateStr
     * @return
     * @throws Exception
     */
    public static Object calcDayOfWeek(String dateStr) throws Exception {
        if (StringUtils.isBlank(dateStr) || dateStr.length() < Constants.DATE_FORMAT.length()) {
            logger.error("==== 不是正确是日期时间参数 ====");
            return null;
        }
        if (!matcherDateFormat(dateStr, Constants.DATE_FORMAT) && dateStr.length() > Constants.DATE_FORMAT.length()) {
            dateStr = dateStr.substring(0, 10);
        }

        Calendar calendar = Calendar.getInstance();
        DateFormat dateFormat = new SimpleDateFormat(Constants.DATE_FORMAT);
        Date date = dateFormat.parse(dateStr);
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 比较两个日期(格式：yyyy-MM-dd HH:mm:ss)的大小
     *
     * @param originalDate 比较的日期
     * @param compareDate  被比较的日期
     * @return 1：大于，-1：小于： 0：相等
     */
    public static int compareToTwoDate(String originalDate, String compareDate, String dateFormatStr) {
        if (StringUtils.isEmpty(originalDate) || StringUtils.isEmpty(compareDate)) {
            logger.error("参数错误！对比的两个日期不能为空！");
            return 0;
        }

        if (StringUtils.isEmpty(dateFormatStr)) {
            dateFormatStr = Constants.DATE_TIME_FULL_FORMAT;
        }

        DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);

        try {
            Date orDate = dateFormat.parse(originalDate);
            Date coDate = dateFormat.parse(compareDate);

            if (orDate.getTime() > coDate.getTime()) {
                return 1;
            } else if (orDate.getTime() < coDate.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception e) {
            logger.error("对比日期时发生错误：" + e.getMessage());
        }
        return 0;
    }

    /**
     * 计算两个日期的时间差
     *
     * @param currentDatetime
     * @param closeDatetime
     * @param unit            差值的单位（day: 天  hour：小时   minute：分钟     second：秒）
     * @return
     */
    public static long calcTimeLengthOfTwoDatetime(String currentDatetime, String closeDatetime, String unit) {
        long timeLength = 0L;
        try {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            Date currentDT = dateFormat.parse(currentDatetime);
            Date closeDT = dateFormat.parse(closeDatetime);
            Calendar currentCal = Calendar.getInstance();
            currentCal.setTime(currentDT);

            Calendar closeCal = Calendar.getInstance();
            closeCal.setTime(closeDT);

            long timeInMillis = closeCal.getTimeInMillis() - currentCal.getTimeInMillis();

            if (unit.equalsIgnoreCase("second")) {
                timeLength = timeInMillis / 1000;
            } else if (unit.equalsIgnoreCase("minute")) {
                timeLength = timeInMillis / (60 * 1000);
            } else if (unit.equalsIgnoreCase("hour")) {
                timeLength = timeInMillis / (60 * 60 * 1000);
            } else {
                timeLength = timeInMillis / (24 * 60 * 60 * 1000);
            }
        } catch (ParseException pe) {
            logger.error("格式化日期对象时发生错误：" + pe.getMessage(), pe);
        }
        return timeLength;
    }

    /**
     * 计算两个日期的时间差
     *
     * @param currentDatetime
     * @param closeDatetime
     * @param unit            差值的单位（day: 天  hour：小时   minute：分钟     second：秒）
     * @return
     */
    public static long calcTimeLengthOfTwoDatetime(Date currentDatetime, Date closeDatetime, String unit) {
        long timeLength = 0L;
        Calendar currentCal = Calendar.getInstance();
        currentCal.setTime(currentDatetime);

        Calendar closeCal = Calendar.getInstance();
        closeCal.setTime(closeDatetime);

        long timeInMillis = closeCal.getTimeInMillis() - currentCal.getTimeInMillis();

        if (unit.equalsIgnoreCase("second")) {
            timeLength = timeInMillis / 1000;
        } else if (unit.equalsIgnoreCase("minute")) {
            timeLength = timeInMillis / (60 * 1000);
        } else if (unit.equalsIgnoreCase("hour")) {
            timeLength = timeInMillis / (60 * 60 * 1000);
        } else {
            timeLength = timeInMillis / (24 * 60 * 60 * 1000);
        }
        return timeLength;
    }
}
